package com.mutual.assistance.task.api;

import com.mutual.assistance.exception.BizException;
import com.mutual.assistance.exception.code.ExceptionCode;
import com.mutual.assistance.response.PageParams;
import com.mutual.assistance.response.PageResult;
import com.mutual.assistance.response.R;
import com.mutual.assistance.task.converter.TaskConverterParams;
import com.mutual.assistance.task.model.dto.*;
import com.mutual.assistance.task.model.po.TaskAuditPO;
import com.mutual.assistance.task.model.vo.*;
import com.mutual.assistance.task.service.TaskPublish;
import com.mutual.assistance.task.utils.SecurityUtil;
import com.mutual.assistance.utils.ThreadLocalUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;

import static com.mutual.assistance.response.R.AUDIT_FALSE;
import static com.mutual.assistance.response.R.*;
import static com.mutual.assistance.task.constant.StringConstant.*;

/**
 * @author chenyuxin
 * @version 1.0
 * @description 任务相关接口
 * @date 2023/4/28 22:49
 */
@RestController
@Slf4j
@Api(tags = "任务相关接口")
public class TaskController {

    @Resource
    private TaskPublish taskPublish;

    @Resource
    private TaskConverterParams taskConverterParams;

    @PostMapping("/prepublish")
    @ApiOperation("用户预发布任务")
    public R<String> prepublish(
            @RequestBody @Validated CreateTaskParamsVO createTaskParamsVO,
            @RequestHeader(AUTHORIZATION) String token
    ) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        ThreadLocalUtils.saveToken(token);
        taskPublish.createTask(createTaskParamsVO, userBO.getUsername());
        return R.success(null, ADDED_SUCCESSFULLY);
    }


    @DeleteMapping("/publish_task/{taskId}")
    @ApiOperation("用户删除未被其他用户接收的发布任务")
    public R<String> deleteTask(@PathVariable("taskId") String taskId, @RequestHeader(AUTHORIZATION) String token) {
        ThreadLocalUtils.saveToken(token);
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        TaskParamsVO preTaskParamsVO = new TaskParamsVO();
        preTaskParamsVO.setTaskId(taskId);
        preTaskParamsVO.setPublisher(userBO.getUsername());
        taskPublish.revokeTask(preTaskParamsVO);
        return R.success(null, SUCCESSFULLY_DELETED);
    }

    @GetMapping("/prepublish/{taskId}")
    @ApiOperation("获取用户发布预发布信息")
    public R<TaskPrePublishPersonDTO> getPersonPreTask(@PathVariable("taskId") String taskId) {//
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        TaskParamsVO preTaskParamsVO = new TaskParamsVO();
        preTaskParamsVO.setTaskId(taskId);
        preTaskParamsVO.setPublisher(userBO.getUsername());
        TaskPrePublishPersonDTO task = taskPublish.getOnePreTask(preTaskParamsVO);
        return R.success(task, QUERY_WAS_SUCCESSFUL);
    }

    @GetMapping("/prepublish/all")
    @ApiOperation("管理员获取用户发布预发布信息进行审核")
    @PreAuthorize("hasAuthority('taskmanager_prepublish_view')")
    public R<PageResult<TaskPrePublishDTO>> getAllPreTask(
            PageParams pageParams, AuditPrePublishTask auditPrePublishTask) {
        PageResult<TaskPrePublishDTO> taskPublishAllTaskToAudit = taskPublish.getAllTaskToAudit(pageParams, auditPrePublishTask);
        return R.success(taskPublishAllTaskToAudit, QUERY_WAS_SUCCESSFUL);
    }

    @GetMapping("/prepublish/all/cache")
    @ApiOperation("管理员获取用户发布预发布信息进行审核缓存版")
    @PreAuthorize("hasAuthority('taskmanager_prepublish_view')")
    public R<PageResult<TaskPrePublishDTO>> getAllPreTask(PageParams pageParams) {
        PageResult<TaskPrePublishDTO> taskPublishAllTaskToAudit = taskPublish.getAllTaskToAuditCache(pageParams);
        return R.success(taskPublishAllTaskToAudit, QUERY_WAS_SUCCESSFUL);
    }

    @PutMapping("/prepublish")
    @ApiOperation("更新预发布表内容")
    public R<String> updatePreTask(@Validated @RequestBody UpdatePreTaskParamsVO updatePreTaskParamsVO) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        taskPublish.updatePreTask(updatePreTaskParamsVO, userBO.getUsername());
        return R.success(null, UPDATE_SUCCESS);
    }

    @PostMapping("/audit")
    @ApiOperation("管理员进行审核并上传审核参数")
    @PreAuthorize("hasAuthority('taskmanager_prepublish_audit')")
    public R<String> audit(@Validated TaskAuditParamsVO auditParamsVO) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        log.info("传入参数：{}", auditParamsVO);
        TaskAuditPO taskAuditPO = taskConverterParams.taskAuditParamsVO2TaskAuditPO(auditParamsVO);
        taskAuditPO.setAuditPeople(userBO.getUsername());
        log.info("获取到转换后参数：{}", taskAuditPO);
        taskPublish.auditPreTask(taskAuditPO);
        return R.success(null, AUDIT_FALSE);
    }

    @PutMapping("/publish_task/{taskId}")
    @ApiOperation("用户下架已发布任务")
    public R<String> editDown(@PathVariable("taskId") String taskId) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        TaskParamsVO taskParamsVO = new TaskParamsVO();
        taskParamsVO.setTaskId(taskId);
        taskParamsVO.setPublisher(userBO.getUsername());
        taskPublish.editDown(taskParamsVO);
        return R.success(null, UPDATE_SUCCESS);
    }

    @GetMapping("/prepublish/user/all")
    @ApiOperation("获取用户所有预发布信息")
    public R<PageResult<TaskPrePublishPersonDTO>> getUserAllPreTask(PageParams pageParams) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        PageResult<TaskPrePublishPersonDTO> userAllPreTask = taskPublish.getUserAllPreTask(pageParams, userBO.getUsername());
        return R.success(userAllPreTask, QUERY_WAS_SUCCESSFUL);
    }

    @DeleteMapping("/prepublish/{taskId}")
    @ApiOperation("用户删除未审核或者审核失败的预发布任务")
    public R<String> deletePreTask(@PathVariable("taskId") String taskId, @RequestHeader(AUTHORIZATION) String token) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        ThreadLocalUtils.saveToken(token);
        TaskParamsVO preTaskParamsVO = new TaskParamsVO();
        preTaskParamsVO.setTaskId(taskId);
        preTaskParamsVO.setPublisher(userBO.getUsername());
        taskPublish.userDeletePreTask(preTaskParamsVO);
        return R.success(null, SUCCESSFULLY_DELETED);
    }


    @GetMapping("/publish_task/all")
    @ApiOperation("获取所有已发布任务")
    public R<PageResult<TaskPublishDTO>> getAllTask(
            PageParams pageParams, TaskFilterParamsVO taskFilterParamsVO
    ) {
        PageResult<TaskPublishDTO> taskPublishDTOPageResult = taskPublish.queryAllTask(pageParams, taskFilterParamsVO);
        return R.success(taskPublishDTOPageResult, QUERY_WAS_SUCCESSFUL);
    }

    @GetMapping("/publish_task/all/second_hand")
    @ApiOperation("获取所有已发布二手交易任务缓存版")
    public R<PageResult<TaskPublishDTO>> getAllTaskCacheSecondHand(PageParams pageParams) {
        PageResult<TaskPublishDTO> taskPublishDTOPageResult = taskPublish.queryAllTaskCache(pageParams, SECOND_HAND_HANDLE);
        return R.success(taskPublishDTOPageResult, QUERY_WAS_SUCCESSFUL);
    }

    @GetMapping("/publish_task/all/assistance")
    @ApiOperation("获取所有已发布任务生活互助缓存版")
    public R<PageResult<TaskPublishDTO>> getAllTaskCacheAssistance(PageParams pageParams) {
        PageResult<TaskPublishDTO> taskPublishDTOPageResult = taskPublish.queryAllTaskCache(pageParams, MUTUAL_ASSISTANCE);
        return R.success(taskPublishDTOPageResult, QUERY_WAS_SUCCESSFUL);
    }

    @GetMapping("/publish_task/all/lean")
    @ApiOperation("获取所有已发布任务学习辅导缓存版")
    public R<PageResult<TaskPublishDTO>> getAllTaskCache(PageParams pageParams) {
        PageResult<TaskPublishDTO> taskPublishDTOPageResult = taskPublish.queryAllTaskCache(pageParams, LEARNING_GUIDANCE);
        return R.success(taskPublishDTOPageResult, QUERY_WAS_SUCCESSFUL);
    }

    @GetMapping("/publish_task/all/question")
    @ApiOperation("获取所有已发布任务问答缓存版")
    public R<PageResult<TaskPublishDTO>> getAllTaskCacheQuest(PageParams pageParams) {
        PageResult<TaskPublishDTO> taskPublishDTOPageResult = taskPublish.queryAllTaskCache(pageParams, QUESTIONS_AND_ANSWERS);
        return R.success(taskPublishDTOPageResult, QUERY_WAS_SUCCESSFUL);
    }


    @GetMapping("/publish_task/user")
    @ApiOperation("获取该用户所有已发布任务")
    public R<PageResult<TaskPublishDTO>> getUserPublishAllTask(
            PageParams pageParams
    ) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        TaskFilterParamsVO taskFilterParamsVO = new TaskFilterParamsVO();
        taskFilterParamsVO.setPublisher(userBO.getUsername());
        PageResult<TaskPublishDTO> taskPublishDTOPageResult = taskPublish.queryAllTask(pageParams, taskFilterParamsVO);
        return R.success(taskPublishDTOPageResult, QUERY_WAS_SUCCESSFUL);
    }

    @GetMapping("/publish_task/user/quest")
    @ApiOperation("获取单条问答任务及其评论")
    public R<PageResult<TaskPublishDTO>> getUserPublishAllTaskQuest (
            PageParams pageParams,
            @RequestParam("taskId") @NotBlank(message = "问答任务主键不能为空") String taskId
    ) {
        TaskFilterParamsVO taskFilterParamsVO = new TaskFilterParamsVO();
        taskFilterParamsVO.setTaskId(taskId);
        taskFilterParamsVO.setType(QUESTIONS_AND_ANSWERS);
        PageResult<TaskPublishDTO> taskPublishDTOPageResult = taskPublish.queryAllTask(pageParams, taskFilterParamsVO);
        return R.success(taskPublishDTOPageResult, QUERY_WAS_SUCCESSFUL);
    }

    @GetMapping("/accept/recipient")
    @ApiOperation("获取该用户所有已接收发布任务")
    public R<PageResult<TaskPublishDTO>> queryAllAcceptedTaskRecipient (PageParams pageParams) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        PageResult<TaskPublishDTO> taskPublishDTOPageResult = taskPublish.queryAllAcceptedTask(pageParams, userBO.getUsername());
        return R.success(taskPublishDTOPageResult, QUERY_WAS_SUCCESSFUL);
    }

    @GetMapping("/accept/publisher")
    @ApiOperation("获取该用户所有已发布已接收任务")
    public R<PageResult<TaskPublishDTO>> queryAllAcceptedTaskPublisher (PageParams pageParams) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        PageResult<TaskPublishDTO> taskPublishDTOPageResult = taskPublish.queryAllAcceptTask(pageParams, userBO.getUsername());
        return R.success(taskPublishDTOPageResult, QUERY_WAS_SUCCESSFUL);
    }


    @GetMapping("/publish_task/all/order")
    @ApiOperation("获取所有已发布任务排序")
    public R<PageResult<TaskPublishDTO>> getAllTaskByOrder(
            PageParams pageParams, TaskOrderParamsVO taskOrderParamsVO
    ) {
        PageResult<TaskPublishDTO> taskPublishDTOPageResult = taskPublish.queryAllTaskByOrder(pageParams, taskOrderParamsVO);
        return R.success(taskPublishDTOPageResult, QUERY_WAS_SUCCESSFUL);
    }

    @PostMapping("/user/comment")
    @ApiOperation("用户添加问答任务评论")
    public R<String> addTaskComment(
            @RequestParam("content") @NotBlank(message = "任务评论内容不能为空") String content,
            @RequestParam("taskId") @NotBlank(message = "任务id不能为空") String taskId
    ) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        AddTaskCommentParamsVO addTaskCommentParamsVO = new AddTaskCommentParamsVO();
        addTaskCommentParamsVO.setContent(content);
        addTaskCommentParamsVO.setUsername(userBO.getUsername());
        addTaskCommentParamsVO.setTaskId(taskId);
        taskPublish.addCommentForTask(addTaskCommentParamsVO);
        return R.success(null, ADDED_SUCCESSFULLY);
    }

    @PutMapping("/publish_task/accept")
    @ApiOperation("用户接收任务")
    public R<String> acceptTask(
            @RequestParam("publisher") @NotBlank(message = "发布者姓名不能为空") String publisher,
            @RequestParam("taskId") @NotBlank(message = "任务id不能为空") String taskId
    ) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        AcceptTaskParamsVO acceptTaskParamsVO = new AcceptTaskParamsVO();
        acceptTaskParamsVO.setTaskId(taskId);
        acceptTaskParamsVO.setPublisher(publisher);
        acceptTaskParamsVO.setRecipient(userBO.getUsername());
        log.info("获取到参数：{}", acceptTaskParamsVO);
        taskPublish.acceptAssignment(acceptTaskParamsVO);
        return R.success(null, UPDATE_SUCCESS);
    }

    @PutMapping("/publish_task/submit")
    @ApiOperation("用户确认提交非问答任务并且评价")
    public R<String> finishTask(@RequestBody @Validated FinishTaskVO finishTaskVO) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        taskPublish.finishTask(finishTaskVO, userBO.getUsername());
        return R.success(null, COMMIT_SUCCESS);
    }

    @DeleteMapping("/user/comment")
    @ApiOperation("删除用户问答任务相关评论")
    public R<String> deleteComment(
            @RequestParam("taskId") @NotBlank(message = "任务id不能为空") String taskId,
            @RequestParam("commentId") @NotBlank(message = "删除的评论消息不能为空") String commentId
    ) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        TaskCommentVO taskCommentVO = new TaskCommentVO();
        taskCommentVO.setCommentId(commentId);
        taskCommentVO.setUsername(userBO.getUsername());
        taskCommentVO.setTaskId(taskId);
        taskPublish.deleteTaskComment(taskCommentVO);
        return R.success(null, SUCCESSFULLY_DELETED);
    }

    @PutMapping("/user/comment")
    @ApiOperation("修改任务评论")
    public R<String> updateComment(
            @RequestBody @Validated UpdateCommentParamsVO updateCommentParamsVO
    ) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        taskPublish.updateComment(updateCommentParamsVO, userBO.getUsername());
        return R.success(null, COMMIT_SUCCESS);
    }

    @GetMapping("/recipient/comments")
    @ApiOperation("接收者获取问答任务相关评论")
    public R<PageResult<CommentDTO>> getTaskCommentCache (
            PageParams pageParams,
            @RequestParam("taskId")  @NotBlank(message = "任务id不能为空") String taskId,
            @RequestParam("publisher") @NotBlank(message = "任务发布者不能为空") String publisher
   ) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        TaskCommentVO taskCommentVO = new TaskCommentVO();
        taskCommentVO.setPublisher(publisher);
        taskCommentVO.setTaskId(taskId);
        taskCommentVO.setUsername(userBO.getUsername());
        PageResult<CommentDTO> taskCommentCache = taskPublish.getTaskCommentCache(pageParams, taskCommentVO);
        return R.success(taskCommentCache, QUERY_WAS_SUCCESSFUL);
    }

    @GetMapping("/comment/all")
    @ApiOperation("获取所有问答任务相关评论")
    public R<PageResult<CommentDTO>> getTaskComment (
            PageParams pageParams, CommentFilterParamsVO commentFilterParamsVO

    ) {
        PageResult<CommentDTO> taskCommentAll = taskPublish.getTaskCommentAll(pageParams, commentFilterParamsVO);
        return R.success(taskCommentAll, QUERY_WAS_SUCCESSFUL);
    }

    @GetMapping("/publisher/comment/all")
    @ApiOperation("发布者获取所有问答任务相关评论")
    public R<PageResult<CommentDTO>> getTaskCommentPublish (
            PageParams pageParams, @NotBlank(message = "任务id不能为空") String taskId

    ) {
        CommentFilterParamsVO commentFilterParamsVO = new CommentFilterParamsVO();
        commentFilterParamsVO.setTaskId(taskId);
        PageResult<CommentDTO> taskCommentAll = taskPublish.getTaskCommentAll(pageParams, commentFilterParamsVO);
        return R.success(taskCommentAll, QUERY_WAS_SUCCESSFUL);
    }

    @GetMapping("/recipient/comment/all")
    @ApiOperation("获取用户相关评论信息,通过内容模糊查询，根据任务进行过滤")
    public R<PageResult<CommentDTO>> getUserTaskComment (
            PageParams pageParams, CommentSmallFilterParamsVO commentSmallFilterParamsVO
    ) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        CommentFilterParamsVO commentFilterParamsVO = new CommentFilterParamsVO();
        commentFilterParamsVO.setUsername(userBO.getUsername());
        commentFilterParamsVO.setContent(commentSmallFilterParamsVO.getContent());
        String taskId = commentSmallFilterParamsVO.getTaskId();
        if (taskId != null) {
            commentFilterParamsVO.setTaskId(taskId);
        }
        PageResult<CommentDTO> taskCommentAll = taskPublish.getTaskCommentAll(pageParams, commentFilterParamsVO);
        return R.success(taskCommentAll, QUERY_WAS_SUCCESSFUL);
    }


    @PutMapping("/publish_task/submit/quest")
    @ApiOperation("提交问答任务")
    public R<String> commitQuestTask(@RequestBody @Validated FinishQuestTaskVO finishTaskVO) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        taskPublish.finishQuestTask(finishTaskVO, userBO.getUsername());
        return R.success(null, COMMIT_SUCCESS);
    }

    @GetMapping("/history/publisher")
    @ApiOperation("获取到发布者所有历史表")
    public R<PageResult<TaskHistoryDTO>> getUserHistoryPublish (
            PageParams pageParams,
            TaskHistoryFilterParamsVO taskHistoryFilterParamsVO
    ) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        PageResult<TaskHistoryDTO> taskHistory = taskPublish.getTaskHistory(pageParams, taskHistoryFilterParamsVO, userBO.getUsername(), null);
        return R.success(taskHistory, QUERY_WAS_SUCCESSFUL);
    }

    @GetMapping("/history/recipient")
    @ApiOperation("获取到接受者所有历史表")
    public R<PageResult<TaskHistoryDTO>> getUserHistoryRecipient (
            PageParams pageParams,
            TaskHistoryFilterParamsVO taskHistoryFilterParamsVO
    ) {
        SecurityUtil.UserBO userBO = checkUserIsLogin();
        PageResult<TaskHistoryDTO> taskHistory = taskPublish.getTaskHistory(pageParams, taskHistoryFilterParamsVO, null, userBO.getUsername());
        return R.success(taskHistory, QUERY_WAS_SUCCESSFUL);
    }

    private static SecurityUtil.UserBO checkUserIsLogin() {
        SecurityUtil.UserBO user = SecurityUtil.getUser();
        if (user == null) {
            log.info("当前用户未登录");
            throw new BizException(ExceptionCode.THE_USER_IS_NOT_LOGGED_IN_OR_THE_USER_DOES_NOT_EXIST.getCode(),
                    ExceptionCode.THE_USER_IS_NOT_LOGGED_IN_OR_THE_USER_DOES_NOT_EXIST.getMsg());
        }
        return user;
    }

}
